package order

import (
	"enjoy_xxz/formdata"
	"enjoy_xxz/internal/model/database/mysql"
	goods2 "enjoy_xxz/internal/model/goods"
	"enjoy_xxz/internal/model/user"
	"enjoy_xxz/pkg"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

type Order struct {
	gorm.Model
	UserID        int64   `gorm:"type:int;comment:下单用户id"`
	No            string  `gorm:"type:varchar(50);comment:订单编号;unique"`
	Name          string  `gorm:"type:varchar(20);comment:收货人姓名"`
	Phone         string  `gorm:"type:char(11);comment:收货人手机号"`
	Address       string  `gorm:"type:varchar(255);comment:地址"`
	Note          string  `gorm:"type:varchar(255);comment:订单备注"`
	CouponID      int64   `gorm:"type:int;comment:优惠券id"`
	Favorable     float64 `gorm:"type:decimal(10,2);comment:优惠价格"`
	Amount        string  `gorm:"type:varchar(30);comment:订单总金额"`
	PayType       int8    `gorm:"type:tinyint(1);comment:支付方式（0支付宝 1微信）"`
	CommentStatus int8    `gorm:"type:tinyint(1);comment:评论状态（0待审核1审核完成2审核失败）"`
	PaymentStatus int8    `gorm:"type:tinyint(1);comment:支付状态（0待支付1支付成功2支付失败）"`
	Status        int8    `gorm:"type:tinyint(1);comment:订单状态（0未支付1待发货）"`
}

// CreateOrder 创建订单并关联商品信息
func (o *Order) CreateOrder(data formdata.OrderCreateReq, addrInfo *user.UserAddress, userID int64) (order Order, err error) {
	return order, mysql.WithMysql(func(db *gorm.DB) error {
		return db.Transaction(func(tx *gorm.DB) error {
			// 1. 提取所有商品的 SKU ID 和数量
			skuIDs := make([]int64, 0, len(data.Pr))
			skuQuantityMap := make(map[int64]int64, len(data.Pr)) // SKU ID -> 数量
			for _, item := range data.Pr {
				skuIDs = append(skuIDs, item.SkuID)
				skuQuantityMap[item.SkuID] = item.Quantity
			}

			// 2. 批量查询 SKU 信息
			var skuList []goods2.GoodsSku
			if err = tx.Model(&goods2.GoodsSku{}).Where("id in (?)", skuIDs).Find(&skuList).Error; err != nil {
				return fmt.Errorf("查询 SKU 信息失败: %v", err)
			}
			if len(skuList) == 0 {
				return fmt.Errorf("未找到任何商品的 SKU 信息")
			}

			// 3. 提取商品 ID
			goodsIDs := make([]int64, 0, len(skuList))
			for _, sku := range skuList {
				goodsIDs = append(goodsIDs, sku.GoodsID)
			}

			// 4. 批量查询商品信息
			var goodsList []goods2.Goods
			if err = tx.Model(&goods2.Goods{}).Where("id in (?)", goodsIDs).Find(&goodsList).Error; err != nil {
				return fmt.Errorf("查询商品信息失败: %v", err)
			}

			// 5. 构建商品信息映射表
			goodsMap := make(map[int64]goods2.Goods)
			for _, goods := range goodsList {
				goodsMap[int64(goods.ID)] = goods
			}

			// 6. 构建 SKU 信息映射表
			skuMap := make(map[int64]goods2.GoodsSku)
			for _, sku := range skuList {
				skuMap[int64(sku.ID)] = sku
			}

			// 7. 计算总金额并扣减库存
			totalAmount := decimal.NewFromInt(0)
			for skuID, quantity := range skuQuantityMap {
				sku, ok := skuMap[skuID]
				if !ok {
					return fmt.Errorf("未找到 SKU ID 为 %d 的商品", skuID)
				}

				// 扣减库存
				if err = reduceStock(tx, sku, quantity); err != nil {
					return err
				}

				// 计算总金额
				price, err := decimal.NewFromString(sku.Price)
				if err != nil {
					return fmt.Errorf("商品 SKU ID 为 %d 的价格格式错误: %v", sku.ID, err)
				}

				skuAmount := price.Mul(decimal.NewFromInt(quantity))
				fmt.Printf("SKU ID: %d, Price: %s, Quantity: %d, Amount: %s\n", skuID, sku.Price, quantity, skuAmount.String())
				totalAmount = totalAmount.Add(skuAmount)
			}
			fmt.Println("订单总金额 ：：：", totalAmount)
			// 8. 生成订单号
			no := uuid.NewString()

			// 9. 创建订单
			order = Order{
				UserID:    userID,
				No:        no,
				Name:      addrInfo.Name,
				Phone:     addrInfo.Phone,
				Address:   addrInfo.Address,
				Note:      data.Note,
				CouponID:  data.CouponID,
				Favorable: 0,
				Amount:    totalAmount.StringFixed(2),
				PayType:   int8(data.PayType),
			}
			if err = tx.Create(&order).Error; err != nil {
				return fmt.Errorf("创建订单失败: %v", err)
			}

			// 10. 创建订单商品关联信息
			for skuID, quantity := range skuQuantityMap {
				sku, ok := skuMap[skuID]
				if !ok {
					return fmt.Errorf("未找到 SKU ID 为 %d 的商品", skuID)
				}

				goods, ok := goodsMap[sku.GoodsID]
				if !ok {
					return fmt.Errorf("未找到商品 ID 为 %d 的商品", sku.GoodsID)
				}

				orderGoods := OrderGoods{
					OrderID:  int64(order.ID),
					GoodID:   sku.GoodsID,
					Title:    goods.Title, // 从商品表中获取 Title
					Img:      goods.Img,   // 从商品表中获取图片
					SKUId:    skuID,
					Quantity: quantity,
					Price:    sku.Price,
				}

				if err = tx.Create(&orderGoods).Error; err != nil {
					return fmt.Errorf("创建订单商品关联信息失败: %v", err)
				}
			}
			return nil
		})
	})
}

// reduceStock 扣减库存
func reduceStock(tx *gorm.DB, sku goods2.GoodsSku, quantity int64) error {
	fmt.Println("扣减", sku)
	if sku.Stock < quantity {
		return fmt.Errorf("商品 SKU ID 为 %d 的库存不足", sku.ID)
	}

	if err := tx.Model(&goods2.GoodsSku{}).
		Where("id = ? and goods_id = ? and stock >= ?", sku.ID, sku.GoodsID, quantity).
		Update("stock", gorm.Expr("stock - ?", quantity)).Error; err != nil {
		return fmt.Errorf("扣减库存失败: %v", err)
	}
	return nil
}

// 订单详情
func (o *Order) GetOrderByID() error {
	return mysql.WithMysql(func(db *gorm.DB) error {
		return db.First(&o).Error
	})
}

// 订单列表
func (o *Order) GetOrderGoodsList() (orderInfo []formdata.OrderGoodsList, err error) {
	var list []Order
	return orderInfo, mysql.WithMysql(func(db *gorm.DB) error {
		//初始化条件
		reqDb := db.Where("user_id = ?", o.UserID)
		//如果状态不为0 则按状态查询
		if o.Status != 0 {
			reqDb = reqDb.Where("status = ?", o.Status)
		}
		err = reqDb.Find(&list).Error
		if err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil
			}
			return errors.New("服务错误")
		}
		infoMap := make(map[int64]Order)
		//获取订单列表的id
		var oIds []int64
		for _, val := range list {
			oIds = append(oIds, int64(val.ID))
			infoMap[int64(val.ID)] = val
		}
		var orderGoodsInfo []OrderGoods
		//查询订单多个商品
		oo := new(OrderGoods)
		err = db.Model(&oo).Where("order_id in(?)", oIds).Find(&orderGoodsInfo).Error

		if err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil
			}
			return err
		}

		//根据订单id 拼接订单下的商品信息
		orderGoodsMap := make(map[int64][]formdata.OrderGoodsInfos)
		for _, val := range orderGoodsInfo {
			//解析图片
			images := pkg.GetImages(val.Img)
			orderGoodsMap[val.OrderID] = append(orderGoodsMap[val.OrderID], formdata.OrderGoodsInfos{
				GoodsId:  val.GoodID,
				SkuId:    val.SKUId,
				Title:    val.Title,
				Img:      images,
				Price:    val.Price,
				Quantity: val.Quantity, // 赋值商品数量
			})
		}

		for _, val := range list {
			// 格式化时间为字符串
			formattedTime := val.CreatedAt.Format("2006-01-02 15:04:05") // 根据需要调整格式
			orderInfo = append(orderInfo, formdata.OrderGoodsList{
				OrderID:    int64(val.ID),
				OrderNo:    val.No,
				Amount:     val.Amount,
				CreateTime: formattedTime,
				PayType:    val.PayType,
				Status:     val.Status,
				AddressInfo: formdata.AddressInfo{
					Name:    val.Name,
					Phone:   val.Phone,
					Details: val.Address,
				},
				OrderGoodsInfo: orderGoodsMap[int64(val.ID)], //根据订单id 进行赋值
			})
		}

		return nil
	})
}
